#if _DEBUG

#include "DesignExtractorTest.h"

#include <cppunit/config/SourcePrefix.h>

// A hack to reset the global PKB
void ResetPKB()
{
	PKB::ast = AST();
	PKB::uses = Uses();
	PKB::parent = Parent();
	PKB::follows = Follows();
	PKB::modifies = Modifies();
	PKB::varTable = VarTable();
	PKB::procTable = ProcTable();
	PKB::shortcutTable = ShortcutTable();
	PKB::calls = CallsTable();
	PKB::next = Next();
	PKB::affects = Affects();
	PKB::nextbip = NextBIP();
	PKB::affectsbip = AffectsBIP();
}


void DesignExtractorTest::setUp()
{
}

void DesignExtractorTest::tearDown()
{
}

CPPUNIT_TEST_SUITE_REGISTRATION( DesignExtractorTest );

void DesignExtractorTest::testSource1()
{
	ResetPKB();

	SPA spa;
	CPPUNIT_ASSERT( spa.LoadFile( "test/TestFile1.txt" ) );
	CPPUNIT_ASSERT( spa.ParseFile() );
	spa.ExtractDesign();

	// FOLLOWS
	// Top level scope
	STMT s1;	s1.node_type=ASSIGN;		s1.statement_number = 1;
	STMT s2 = PKB::follows.GetFollowing( s1 );
	STMT s3 = PKB::follows.GetFollowing( s2 );
	STMT s4 = PKB::follows.GetFollowing( s3 );
	STMT s9 = PKB::follows.GetFollowing( s4 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( s2.statement_number == 2 );
	CPPUNIT_ASSERT( s3.statement_number == 3 );
	CPPUNIT_ASSERT( s4.statement_number == 4 );
	CPPUNIT_ASSERT( s9.statement_number == 9 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s9 ).statement_number == -1 );

	// 2nd level scope of while at statement 4
	STMT s5;	s5.node_type=ASSIGN;		s5.statement_number = 5;
	STMT s6 = PKB::follows.GetFollowing( s5 );
	STMT s7 = PKB::follows.GetFollowing( s6 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s5 ).statement_number == -1 );
	CPPUNIT_ASSERT( s6.statement_number == 6 );
	CPPUNIT_ASSERT( s7.statement_number == 7 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s7 ).statement_number == -1 );

	// 3nd level scope of while at statement 7
	STMT s8;	s8.node_type=ASSIGN;		s8.statement_number = 8;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s8 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s8 ).statement_number == -1 );

	// Parent
	CPPUNIT_ASSERT( PKB::parent.GetParent( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s2 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s3 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s4 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s5 ).statement_number == 4 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s6 ).statement_number == 4 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s7 ).statement_number == 4 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s8 ).statement_number == 7 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s9 ).statement_number == -1 );

	// Uses
	VARINDEX_ARRAY vars;
	STRING_ARRAY names;

	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s1 ).empty() );
	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s2 ).empty() );
	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s3 ).empty() );
	vars = PKB::uses.GetVariablesUsedByContainer( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 5 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s5 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s6 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByContainer( s7 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s8 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s9 ).empty() );

	// Modifies
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s1 ) ).compare( "x" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s2 ) ).compare( "z" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s3 ) ).compare( "i" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s5 ) ).compare( "x" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s6 ) ).compare( "i" ) == 0 );
	names.clear();
	vars = PKB::modifies.GetVariablesModifiedByContainer( s7 );
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s8 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s9 ) ).compare( "x" ) == 0 );
}

void DesignExtractorTest::testSource2()
{
	ResetPKB();

	SPA spa;
	CPPUNIT_ASSERT( spa.LoadFile( "test/TestFile2.txt" ) );
	CPPUNIT_ASSERT( spa.ParseFile() );
	spa.ExtractDesign();
	
	// FOLLOWS
	// Top level scope
	STMT s1;	s1.node_type=ASSIGN;		s1.statement_number = 1;
	STMT s2 = PKB::follows.GetFollowing( s1 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( s2.statement_number == 2 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s2 ).statement_number == -1 );

	// 2nd level scope of while at statement 2
	STMT s3;	s3.node_type=ASSIGN;		s3.statement_number = 3;
	STMT s4 = PKB::follows.GetFollowing( s3 );
	STMT s6 = PKB::follows.GetFollowing( s4 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s3 ).statement_number == -1 );
	CPPUNIT_ASSERT( s4.statement_number == 4 );
	CPPUNIT_ASSERT( s6.statement_number == 6 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s6 ).statement_number == -1 );

	// 3nd level scope of while at statement 4
	STMT s5;	s5.node_type=ASSIGN;		s5.statement_number = 5;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s5 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s5 ).statement_number == -1 );

	// Parent
	CPPUNIT_ASSERT( PKB::parent.GetParent( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s2 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s3 ).statement_number == 2 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s4 ).statement_number == 2 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s5 ).statement_number == 4 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s6 ).statement_number == 2 );

	// Uses
	VARINDEX_ARRAY vars;
	STRING_ARRAY names;

	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s1 ).empty() );
	vars = PKB::uses.GetVariablesUsedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 5 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s3 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByContainer( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s5 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s6 ).empty() );

	// Modifies
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s1 ) ).compare( "x" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s3 ) ).compare( "x" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s4 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s5 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s6 ) ).compare( "x" ) == 0 );
}

void DesignExtractorTest::testSource3()
{
	ResetPKB();

	SPA spa;
	CPPUNIT_ASSERT( spa.LoadFile( "test/TestFile3.txt" ) );
	CPPUNIT_ASSERT( spa.ParseFile() );
	spa.ExtractDesign();
	
	// FOLLOWS
	// Top level scope
	STMT s1;	s1.node_type=ASSIGN;		s1.statement_number = 1;
	STMT s2 = PKB::follows.GetFollowing( s1 );
	STMT s4 = PKB::follows.GetFollowing( s2 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( s2.statement_number == 2 );
	CPPUNIT_ASSERT( s4.statement_number == 4 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s4 ).statement_number == -1 );

	// 2nd level scope of while at statement 2
	STMT s3;	s3.node_type=ASSIGN;		s3.statement_number = 3;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s3 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s3 ).statement_number == -1 );

	// 2nd level scope of while at statement 4
	STMT s5;	s5.node_type=ASSIGN;		s5.statement_number = 5;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s5 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s5 ).statement_number == -1 );

	// Parent
	CPPUNIT_ASSERT( PKB::parent.GetParent( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s2 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s3 ).statement_number == 2 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s4 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s5 ).statement_number == 4 );

	// Uses
	VARINDEX_ARRAY vars;
	STRING_ARRAY names;

	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s1 ).empty() );
	vars = PKB::uses.GetVariablesUsedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s3 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByContainer( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s5 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );

	// Modifies
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s1 ) ).compare( "x" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s3 ) ).compare( "x" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s5 ) ).compare( "a" ) == 0 );
}

void DesignExtractorTest::testSource4()
{
	ResetPKB();

	SPA spa;
	CPPUNIT_ASSERT( spa.LoadFile( "test/TestFile4.txt" ) );
	CPPUNIT_ASSERT( spa.ParseFile() );
	spa.ExtractDesign();
	
	// FOLLOWS
	// Top level scope
	STMT s1;	s1.node_type=ASSIGN;		s1.statement_number = 1;
	STMT s2 = PKB::follows.GetFollowing( s1 );
	STMT s4 = PKB::follows.GetFollowing( s2 );
	STMT s5 = PKB::follows.GetFollowing( s4 );
	STMT s7 = PKB::follows.GetFollowing( s5 );
	STMT s8 = PKB::follows.GetFollowing( s7 );
	STMT s9 = PKB::follows.GetFollowing( s8 );

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( s2.statement_number == 2 );
	CPPUNIT_ASSERT( s4.statement_number == 4 );
	CPPUNIT_ASSERT( s5.statement_number == 5 );
	CPPUNIT_ASSERT( s7.statement_number == 7 );
	CPPUNIT_ASSERT( s8.statement_number == 8 );
	CPPUNIT_ASSERT( s9.statement_number == 9 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s9 ).statement_number == -1 );

	// 2nd level scope of while at statement 2
	STMT s3;	s3.node_type=ASSIGN;		s3.statement_number = 3;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s3 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s3 ).statement_number == -1 );

	// 3nd level scope of while at statement 5
	STMT s6;	s6.node_type=ASSIGN;		s6.statement_number = 6;

	CPPUNIT_ASSERT( PKB::follows.GetPrevious( s6 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::follows.GetFollowing( s6 ).statement_number == -1 );

	// Parent
	CPPUNIT_ASSERT( PKB::parent.GetParent( s1 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s2 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s3 ).statement_number == 2 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s4 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s5 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s6 ).statement_number == 5 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s7 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s8 ).statement_number == -1 );
	CPPUNIT_ASSERT( PKB::parent.GetParent( s9 ).statement_number == -1 );

	// Uses
	VARINDEX_ARRAY vars;
	STRING_ARRAY names;

	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s1 ).empty() );
	vars = PKB::uses.GetVariablesUsedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "i" ) != names.end() );
	CPPUNIT_ASSERT( PKB::uses.GetVariablesUsedByAssignment( s3 ).empty() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s4 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByContainer( s5 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s6 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 2 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s7 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s8 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 3 );
	CPPUNIT_ASSERT( names.find( "s" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	CPPUNIT_ASSERT( names.find( "z" ) != names.end() );
	vars = PKB::uses.GetVariablesUsedByAssignment( s9 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "y" ) != names.end() );
	
	// Modifies
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s1 ) ).compare( "x" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s2 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "x" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s3 ) ).compare( "x" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s4 ) ).compare( "a" ) == 0 );
	vars = PKB::modifies.GetVariablesModifiedByContainer( s5 );
	names.clear();
	for_each( vars.begin(), vars.end(), [ &names ] ( VARINDEX index )
	{
		names.insert( PKB::varTable.GetVarName( index ) );
	});
	CPPUNIT_ASSERT( names.size() == 1 );
	CPPUNIT_ASSERT( names.find( "a" ) != names.end() );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s6 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s7 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s8 ) ).compare( "a" ) == 0 );
	CPPUNIT_ASSERT( PKB::varTable.GetVarName( PKB::modifies.GetVariableModifiedByAssignment( s9 ) ).compare( "a" ) == 0 );
}

#endif